<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>告警推送系统</title>
    <link rel="icon" type="image/svg+xml" href="/favicon.svg">
    <link rel="shortcut icon" href="/favicon.svg">
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
            background-color: #111827;
            color: #e5e7eb;
            margin: 0;
            padding: 0;
            height: 100vh;
            overflow: hidden;
        }
        
        .app-container {
            display: flex;
            height: 100vh;
        }
        
        .sidebar {
            width: 173px;
            background: #1f2937;
            color: #e5e7eb;
            padding: 0;
            box-shadow: none;
            border-right: 1px solid #374151;
            overflow-y: auto;
        }
        
        .sidebar-header {
            padding: 24px 20px;
            text-align: center;
            border-bottom: 1px solid #374151;
            background: #111827;
        }
        
        .sidebar-header h1 {
            font-size: 1.5em;
            margin-bottom: 5px;
        }
        
        .sidebar-header p {
            font-size: 0.9em;
            opacity: 0.8;
        }
        
        .nav-menu {
            padding: 0;
            list-style: none;
        }
        
        .nav-item {
            border-bottom: none;
        }
        
        .nav-link {
            display: flex;
            align-items: center;
            padding: 16px 15px;
            color: #9ca3af;
            text-decoration: none;
            transition: all 0.2s ease;
            cursor: pointer;
            font-weight: 500;
            border-radius: 0;
        }
        
        .nav-icon {
            width: 22px;
            height: 22px;
            margin-right: 6px;
            fill: currentColor;
            flex-shrink: 0;
        }
        
        .nav-link:hover {
            background: #374151;
            color: #ffffff;
        }
        
        .nav-link.active {
            background: #0d9488;
            color: #ffffff;
            font-weight: 600;
        }
        
        .nav-link i {
            margin-right: 10px;
            width: 16px;
        }
        
        /* 多级导航样式 */
        .nav-item.has-submenu > .nav-link {
            position: relative;
        }
        
        .nav-item.has-submenu > .nav-link::after {
            content: '▶';
            position: absolute;
            right: 15px;
            transition: transform 0.3s ease;
            font-size: 12px;
        }
        
        .nav-item.has-submenu.expanded > .nav-link::after {
            transform: rotate(90deg);
        }
        
        .submenu {
            max-height: 0;
            overflow: hidden;
            transition: max-height 0.25s ease;
            background: #111827;
        }
        
        .nav-item.expanded .submenu {
            max-height: 500px;
        }
        
        .submenu .nav-item {
            padding-left: 20px;
        }
        
        .submenu .nav-link {
            padding: 12px 20px 12px 40px;
            font-size: 14px;
            font-weight: 400;
        }
        
        .submenu .nav-link i {
            width: 12px;
            font-size: 12px;
        }
        
        .log-channels {
            color: #059669;
            font-size: 12px;
            margin-top: 5px;
            font-weight: bold;
        }
        
        .main-content {
            flex: 1;
            display: flex;
            flex-direction: column;
            overflow: hidden;
        }
        
        .top-bar {
            background: #e5e7eb;
            padding: 20px 32px;
            border-bottom: 1px solid #d1d5db;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        
        .page-title {
            font-size: 1.5em;
            font-weight: 600;
            color: #1f2937;
            margin: 0;
        }
        
        .stats-mini {
            color: #374151;
            margin-left: -64px;
        }
        
        .stats-mini strong {
            color: #1f2937;
        }
        
        .content-area {
            flex: 1;
            padding: 32px;
            overflow-y: auto;
            background: #f8fafc;
        }
        
        .stats-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 20px;
            margin-bottom: 30px;
        }
        
        .stat-card {
            background: #ffffff;
            padding: 24px;
            border-radius: 8px;
            border: 1px solid #e2e8f0;
            text-align: center;
            transition: border-color 0.2s ease;
            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
        }
        
        .stat-card:hover {
            border-color: #0d9488;
        }
        
        .stat-number {
            font-size: 2.25em;
            font-weight: 600;
            color: #0d9488;
            margin-bottom: 8px;
        }
        
        .stat-label {
            color: #64748b;
            font-size: 1em;
            font-weight: 500;
        }
        
        .content-area h3,
        .content-area h4,
        .content-area h5 {
            color: #1e293b;
            margin-bottom: 16px;
        }
        
        .content-area p {
            color: #475569;
        }
        
        .content-area span,
        .content-area small {
            color: #374151;
        }
        
        .switch-label {
            color: #374151;
            font-weight: 500;
        }
        
        .content-area strong {
            color: #1e293b;
        }
        
        .notification-channel h4,
        .notification-channel label {
            color: #374151;
        }
        
        .notification-channel small {
            color: #64748b;
        }
        
        .status-indicator {
            color: #374151;
        }
        
        .page {
            display: none;
        }
        
        .page.active {
            display: block;
        }
        
        .log-container {
            background: #ffffff;
            border: 1px solid #e2e8f0;
            border-radius: 6px;
            height: 400px;
            overflow-y: auto;
            padding: 16px;
            font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
            font-size: 13px;
            color: #334155;
            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
        }
        
        .log-entry {
            margin-bottom: 8px;
            padding: 12px;
            background: #f1f5f9;
            border-left: 3px solid #0d9488;
            border-radius: 6px;
        }
        
        .log-timestamp {
            color: #64748b;
            font-weight: bold;
        }
        
        .log-source {
            color: #059669;
            font-weight: bold;
        }
        
        .log-message {
            margin-top: 5px;
            word-wrap: break-word;
            color: #334155;
        }
        
        .alert-entry {
            border-left-color: #dc2626;
            background: #fef2f2;
        }
        
        .service-entry {
            border-left-color: #d97706;
            background: #fffbeb;
        }
        
        .form-group {
            margin-bottom: 20px;
        }
        
        .form-group label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
            color: #374151;
        }
        
        .form-group input,
        .form-group textarea {
            width: 100%;
            padding: 8px 12px;
            border: 1px solid #d1d5db;
            border-radius: 6px;
            font-size: 14px;
            background: #ffffff;
            color: #374151;
            transition: border-color 0.2s ease;
        }
        
        .form-group input:focus,
        .form-group textarea:focus {
            outline: none;
            border-color: #0d9488;
            box-shadow: 0 0 0 3px rgba(13, 148, 136, 0.1);
        }
        
        .form-group textarea {
            height: 100px;
            resize: vertical;
        }
        
        .form-row {
            display: flex;
            align-items: end;
            gap: 10px;
            margin-bottom: 15px;
        }
        
        .form-row .form-group {
            margin-bottom: 0;
        }
        
        .email-account-card {
            background: #ffffff;
            border: 1px solid #e2e8f0;
            border-radius: 8px;
            padding: 20px;
            margin-bottom: 16px;
            transition: border-color 0.2s ease;
            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
        }
        
        .email-account-card:hover {
            border-color: #0d9488;
        }
        
        .btn-sm {
            padding: 6px 12px;
            font-size: 0.875em;
        }
        
        .btn {
            background: #0d9488;
            color: white;
            border: 1px solid #0d9488;
            padding: 8px 16px;
            border-radius: 6px;
            cursor: pointer;
            font-size: 14px;
            font-weight: 500;
            transition: all 0.2s ease;
            margin-right: 8px;
            margin-bottom: 8px;
            display: inline-flex;
            align-items: center;
            justify-content: center;
        }
        
        .btn:hover {
            background: #0f766e;
            border-color: #0f766e;
        }
        
        .btn-success {
            background: #059669;
            border-color: #059669;
        }
        
        .btn-success:hover {
            background: #047857;
            border-color: #047857;
        }
        
        .btn-danger {
            background: #dc2626;
            border-color: #dc2626;
        }
        
        .btn-danger:hover {
            background: #b91c1c;
            border-color: #b91c1c;
        }
        
        .btn-warning {
            background: #d97706;
            border-color: #d97706;
            color: white;
        }
        
        .btn-warning:hover {
            background: #b45309;
            border-color: #b45309;
        }
        
        .status-indicator {
            display: inline-block;
            width: 12px;
            height: 12px;
            border-radius: 50%;
            margin-right: 8px;
        }
        
        .status-running {
            background: #28a745;
        }
        
        .status-stopped {
            background: #dc3545;
        }
        
        .config-grid {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 30px;
        }
        
        @media (max-width: 768px) {
            .config-grid {
                grid-template-columns: 1fr;
            }
            
            .stats-grid {
                grid-template-columns: 1fr;
            }
        }
        
        .alert {
            padding: 15px;
            margin-bottom: 20px;
            border-radius: 5px;
            border-left: 4px solid;
        }
        
        .alert-success {
            background: #d4edda;
            border-color: #28a745;
            color: #155724;
        }
        
        .alert-error {
            background: #f8d7da;
            border-color: #dc3545;
            color: #721c24;
        }
        
        /* 通知渠道配置样式 */
        .notification-channel {
            background: white;
            border: 1px solid #dee2e6;
            border-radius: 10px;
            padding: 20px;
            margin-bottom: 20px;
        }
        
        .channel-config {
            margin-top: 15px;
            padding-top: 15px;
            border-top: 1px solid #eee;
        }
        
        /* 开关按钮样式 */
        .switch {
            position: relative;
            display: inline-block;
            width: 44px;
            height: 24px;
            vertical-align: middle;
        }
        
        .switch input {
            opacity: 0;
            width: 0;
            height: 0;
        }
        
        .slider {
            position: absolute;
            cursor: pointer;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: #ccc;
            transition: .4s;
            border-radius: 24px;
        }
        
        .slider:before {
            position: absolute;
            content: "";
            height: 18px;
            width: 18px;
            left: 3px;
            bottom: 3px;
            background-color: white;
            transition: .4s;
            border-radius: 50%;
        }
        
        input:checked + .slider {
            background-color: #667eea;
        }
        
        input:checked + .slider:before {
            transform: translateX(20px);
        }
        
        .channel-config.disabled {
            opacity: 0.7;
            pointer-events: none;
        }
    </style>
</head>
<body>
    <div class="app-container">
        <!-- 左侧导航栏 -->
        <div class="sidebar">
            <div class="sidebar-header">
                <h1 style="font-size: 16px;">告警推送系统</h1>
            </div>
            <ul class="nav-menu">
                <!-- 1. 导航页 -->
                <li class="nav-item">
                    <a class="nav-link active" onclick="showPage('dashboard')">
                        <svg class="nav-icon" viewBox="0 0 24 24">
                            <path d="M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z"/>
                        </svg>
                        导航页
                    </a>
                </li>
                
                <!-- 2. 数据采集 -->
                <li class="nav-item has-submenu" onclick="toggleSubmenu(this)">
                    <a class="nav-link">
                        <svg class="nav-icon" viewBox="0 0 24 24">
                            <path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-5 14H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z"/>
                        </svg>
                        数据采集
                    </a>
                    <ul class="submenu">
                        <li class="nav-item">
                            <a class="nav-link" onclick="event.stopPropagation(); showPage('email')">
                                邮件采集
                            </a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" onclick="event.stopPropagation(); showPage('webhook')">
                                Webhook配置
                            </a>
                        </li>
                    </ul>
                </li>
                
                <!-- 3. 通知配置 -->
                <li class="nav-item has-submenu" onclick="toggleSubmenu(this)">
                    <a class="nav-link">
                        <svg class="nav-icon" viewBox="0 0 24 24">
                            <path d="M12 22c1.1 0 2-.9 2-2h-4c0 1.1.9 2 2 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z"/>
                        </svg>
                        通知配置
                    </a>
                    <ul class="submenu">
                        <li class="nav-item">
                            <a class="nav-link" onclick="event.stopPropagation(); showPage('social-tools')">
                                即时通讯
                            </a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" onclick="event.stopPropagation(); showPage('sms')">
                                短信
                            </a>
                        </li>
                    </ul>
                </li>
                
                <!-- 4. 日志查询 -->
                <li class="nav-item has-submenu" onclick="toggleSubmenu(this)">
                    <a class="nav-link">
                        <svg class="nav-icon" viewBox="0 0 24 24">
                            <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/>
                        </svg>
                        日志查询
                    </a>
                    <ul class="submenu">
                        <li class="nav-item">
                            <a class="nav-link" onclick="event.stopPropagation(); showPage('logs')">
                                syslog日志
                            </a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" onclick="event.stopPropagation(); showPage('alerts')">
                                告警事件
                            </a>
                        </li>
                    </ul>
                </li>
                
                <!-- 5. 系统配置 -->
                <li class="nav-item has-submenu" onclick="toggleSubmenu(this)">
                    <a class="nav-link">
                        <svg class="nav-icon" viewBox="0 0 24 24">
                            <path d="M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61 l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41 h-3.84c-0.24,0-0.43,0.17-0.47,0.41L9.25,5.35C8.66,5.59,8.12,5.92,7.63,6.29L5.24,5.33c-0.22-0.08-0.47,0-0.59,0.22L2.74,8.87 C2.62,9.08,2.66,9.34,2.86,9.48l2.03,1.58C4.84,11.36,4.8,11.69,4.8,12s0.02,0.64,0.07,0.94l-2.03,1.58 c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-0.96c0.5,0.38,1.03,0.7,1.62,0.94l0.36,2.54 c0.05,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.47-0.41l0.36-2.54c0.59-0.24,1.13-0.56,1.62-0.94l2.39,0.96 c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.22,0.07-0.47-0.12-0.61L19.14,12.94z M12,15.6c-1.98,0-3.6-1.62-3.6-3.6 s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z"/>
                        </svg>
                        系统配置
                    </a>
                    <ul class="submenu">
                        <li class="nav-item">
                            <a class="nav-link" onclick="event.stopPropagation(); showPage('service-management')">
                                服务管理
                            </a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" onclick="event.stopPropagation(); showPage('basic-config')">
                                基础配置
                            </a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" onclick="event.stopPropagation(); showPage('test')">
                                告警测试
                            </a>
                        </li>
                    </ul>
                </li>
            </ul>
        </div>
        
        <!-- 主内容区域 -->
        <div class="main-content">
            <div class="top-bar">
                <div class="page-title" id="page-title">仪表盘</div>
                <div class="stats-mini">
                    <span>
                        <svg style="width: 20px; height: 20px; margin-right: 2px; vertical-align: middle; fill: currentColor;" viewBox="0 0 24 24">
                            <path d="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z"/>
                        </svg>
                        日志: <strong id="mini-logs">0</strong>
                    </span>
                    <span style="margin-left: 20px;">
                        <svg style="width: 20px; height: 20px; margin-right: 2px; vertical-align: middle; fill: currentColor;" viewBox="0 0 24 24">
                            <path d="M10,21H14A2,2 0 0,1 12,23A2,2 0 0,1 10,21M21,19V20H3V19L5,17V11C5,7.9 7.03,5.17 10,4.29C10,4.19 10,4.1 10,4A2,2 0 0,1 12,2A2,2 0 0,1 14,4C14,4.1 14,4.19 14,4.29C16.97,5.17 19,7.9 19,11V17L21,19M17,11A5,5 0 0,0 12,6A5,5 0 0,0 7,11V18H17V11Z"/>
                        </svg>
                        告警: <strong id="mini-alerts">0</strong>
                    </span>
                    <span style="margin-left: 20px;">
                        <svg style="width: 20px; height: 20px; margin-right: 2px; vertical-align: middle; fill: currentColor;" viewBox="0 0 24 24">
                            <path d="M12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22C6.47,22 2,17.53 2,12A10,10 0 0,1 12,2M12.5,7V12.25L17,14.92L16.25,16.15L11,13V7H12.5Z"/>
                        </svg>
                        运行: <strong id="mini-uptime">0秒</strong>
                    </span>
                </div>
            </div>
            
            <div class="content-area">
                <!-- 仪表盘页面 -->
                <div id="dashboard" class="page active">
                    <div style="margin-bottom: 30px;">
                        <h3>系统概览</h3>
                        <p>欢迎使用告警推送系统。系统正在实时监控日志并根据配置的规则发送告警通知。</p>
                        
                        <div style="margin-top: 20px;">
                            <h4>快速操作</h4>
                            <div style="display: flex; gap: 15px; margin-top: 10px;">
                                <button class="btn" onclick="showPage('logs')">查看实时日志</button>
                                <button class="btn" onclick="showPage('alerts')">查看告警事件</button>
                                <button class="btn" onclick="showPage('config')">系统配置</button>
                                <button class="btn" onclick="showPage('test')">告警测试</button>
                            </div>
                        </div>
                    </div>
                    
                    <div class="stats-grid">
                        <div class="stat-card">
                            <div class="stat-number" id="received-logs">0</div>
                            <div class="stat-label">接收日志数</div>
                        </div>
                        <div class="stat-card">
                            <div class="stat-number" id="sent-alerts">0</div>
                            <div class="stat-label">发送告警数</div>
                        </div>
                        <div class="stat-card">
                            <div class="stat-number" id="failed-alerts">0</div>
                            <div class="stat-label">失败告警数</div>
                        </div>
                        <div class="stat-card">
                            <div class="stat-number" id="checked-emails">0</div>
                            <div class="stat-label">检查邮件数</div>
                        </div>
                        <div class="stat-card">
                            <div class="stat-number" id="email-alerts">0</div>
                            <div class="stat-label">邮件告警数</div>
                        </div>
                        <div class="stat-card">
                            <div class="stat-number" id="uptime">00:00:00</div>
                            <div class="stat-label">运行时间</div>
                        </div>
                    </div>
                    
                    <!-- TOP10 IP统计卡片 -->
                    <div style="background: white; padding: 20px; border-radius: 10px; margin-top: 30px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
                        <h4 style="margin-bottom: 15px; color: #374151;">TOP10 来源IP统计</h4>
                        <div id="top-ip-stats-container" style="max-height: 300px; overflow-y: auto;">
                            <div style="text-align: center; color: #64748b; padding: 20px;">正在加载TOP10 IP统计数据...</div>
                        </div>
                    </div>
                </div>
                
                <!-- 实时日志页面 -->
                <div id="logs" class="page">
                <h3>实时Syslog日志</h3>
                
                <!-- IP统计表 -->
                <div style="background: white; padding: 20px; border-radius: 10px; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
                    <h4>来源IP统计</h4>
                    <div style="overflow-x: auto;">
                        <table style="width: 100%; border-collapse: collapse; margin-top: 15px;">
                            <thead>
                                <tr style="background: #f8fafc; border-bottom: 2px solid #e2e8f0;">
                                    <th style="padding: 12px; text-align: left; color: #374151; font-weight: 600;">排名</th>
                                    <th style="padding: 12px; text-align: left; color: #374151; font-weight: 600;">来源IP</th>
                                    <th style="padding: 12px; text-align: left; color: #374151; font-weight: 600;">日志数量</th>
                                    <th style="padding: 12px; text-align: left; color: #374151; font-weight: 600;">占比</th>
                                    <th style="padding: 12px; text-align: left; color: #374151; font-weight: 600;">统计图</th>
                                </tr>
                            </thead>
                            <tbody id="ip-stats-table">
                                <tr>
                                    <td colspan="5" style="padding: 20px; text-align: center; color: #64748b;">正在加载IP统计数据...</td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                    
                    <div class="pagination" id="ip-stats-pagination" style="margin-top: 15px; text-align: center;">
                        <button class="btn" onclick="goToIpStatsPage(1)" id="ip-stats-first-page">首页</button>
                        <button class="btn" onclick="goToIpStatsPage(currentIpStatsPage - 1)" id="ip-stats-prev-page">上一页</button>
                        <span style="margin: 0 15px;">第 <span id="current-ip-stats-page">1</span> 页，共 <span id="total-ip-stats-pages">1</span> 页</span>
                        <button class="btn" onclick="goToIpStatsPage(currentIpStatsPage + 1)" id="ip-stats-next-page">下一页</button>
                        <button class="btn" onclick="goToIpStatsPage(totalIpStatsPages)" id="ip-stats-last-page">末页</button>
                        <span style="margin-left: 15px;">每页显示10条</span>
                    </div>
                </div>
                
                <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
                    <p>显示最近接收到的syslog日志信息</p>
                    <div>
                        <button class="btn btn-warning" onclick="clearLogs()">清空日志</button>
                        <button class="btn" onclick="refreshLogs()">刷新</button>
                    </div>
                </div>
                
                <div class="log-container" id="logs-container">
                    <div class="log-entry">
                        <div class="log-timestamp">等待日志数据...</div>
                    </div>
                </div>
                
                <div class="pagination" id="logs-pagination" style="margin-top: 15px; text-align: center;">
                    <button class="btn" onclick="goToPage(1)" id="first-page">首页</button>
                    <button class="btn" onclick="goToPage(currentPage - 1)" id="prev-page">上一页</button>
                    <span style="margin: 0 15px;">第 <span id="current-page">1</span> 页，共 <span id="total-pages">1</span> 页</span>
                    <button class="btn" onclick="goToPage(currentPage + 1)" id="next-page">下一页</button>
                    <button class="btn" onclick="goToPage(totalPages)" id="last-page">末页</button>
                    <select id="page-size" onchange="changePageSize()" style="margin-left: 15px; padding: 5px;">
                        <option value="10">10条/页</option>
                        <option value="20" selected>20条/页</option>
                        <option value="50">50条/页</option>
                        <option value="100">100条/页</option>
                    </select>
                </div>
            </div>
            
            <!-- 告警事件页面 -->
            <div id="alerts" class="page">
                <h3>告警事件日志</h3>
                <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
                    <p>显示触发的告警事件和发送状态</p>
                    <div>
                        <button class="btn btn-warning" onclick="clearAlerts()">清空告警</button>
                        <button class="btn" onclick="refreshAlerts()">刷新</button>
                    </div>
                </div>
                
                <div class="log-container" id="alerts-container">
                    <div class="log-entry">
                        <div class="log-timestamp">等待告警数据...</div>
                    </div>
                </div>
                
                <div class="pagination" id="alerts-pagination" style="margin-top: 15px; text-align: center;">
                    <button class="btn" onclick="goToAlertsPage(1)" id="alerts-first-page">首页</button>
                    <button class="btn" onclick="goToAlertsPage(currentAlertsPage - 1)" id="alerts-prev-page">上一页</button>
                    <span style="margin: 0 15px;">第 <span id="current-alerts-page">1</span> 页，共 <span id="total-alerts-pages">1</span> 页</span>
                    <button class="btn" onclick="goToAlertsPage(currentAlertsPage + 1)" id="alerts-next-page">下一页</button>
                    <button class="btn" onclick="goToAlertsPage(totalAlertsPages)" id="alerts-last-page">末页</button>
                    <select id="alerts-page-size" onchange="changeAlertsPageSize()" style="margin-left: 15px; padding: 5px;">
                        <option value="10">10条/页</option>
                        <option value="20" selected>20条/页</option>
                        <option value="50">50条/页</option>
                        <option value="100">100条/页</option>
                    </select>
                </div>
            </div>
            
            <!-- 服务管理页面 -->
            <div id="service-management" class="page">
                <h3>服务管理</h3>
                <div id="service-management-alert"></div>
                
                <!-- 服务状态管理 -->
                <div style="background: white; padding: 20px; border-radius: 10px; margin-bottom: 30px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
                    <h4>服务状态管理</h4>
                    <p style="margin: 15px 0;">
                        <span class="status-indicator" id="status-indicator"></span>
                        服务状态: <span id="server-status">检查中...</span>
                    </p>
                    <p style="margin: 15px 0;">
                        监听端口: <span id="server-port">-</span>
                    </p>
                    <div style="margin: 20px 0;">
                        <button class="btn btn-success" onclick="startServer()">启动服务</button>
                        <button class="btn btn-danger" onclick="stopServer()">停止服务</button>
                    </div>
                    <h5>服务日志</h5>
                    <div class="log-container" id="service-logs-container" style="height: 200px;">
                        <div class="service-entry">
                            <div class="log-timestamp">等待服务日志...</div>
                        </div>
                    </div>
                </div>
            </div>
            
            <!-- 基础配置页面 -->
            <div id="basic-config" class="page">
                <h3>基础配置</h3>
                <div id="basic-config-alert"></div>
                
                <!-- 基础配置 -->
                <div style="background: white; padding: 20px; border-radius: 10px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
                    <h4>基础配置</h4>
                    <div style="max-width: 600px;">
                        <div class="form-group">
                            <label>Syslog端口:</label>
                            <input type="number" id="syslog-port" value="514">
                        </div>
                        <div class="form-group">
                            <label>Web端口:</label>
                            <input type="number" id="web-port" value="5000">
                        </div>
                        <div class="form-group">
                            <label>告警关键词 (逗号分隔):</label>
                            <input type="text" id="alert-keywords" value="error,critical,alert,emergency">
                        </div>
                        <div class="form-group">
                            <label>最大日志缓存数量:</label>
                            <input type="number" id="max-logs" value="10000">
                        </div>
                    </div>
                    <button class="btn" onclick="saveBasicConfig()">保存配置</button>
                    <button class="btn btn-warning" onclick="loadBasicConfig()">重新加载</button>
                </div>
            </div>
            

            
            <!-- 社交工具页面 -->
            <div id="social-tools" class="page">
                <h3>即时通讯配置</h3>
                <div id="social-tools-alert"></div>
                
                <!-- 钉钉配置 -->
                <div class="notification-channel">
                    <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
                        <h4>钉钉群机器人</h4>
                        <label class="switch">
                            <input type="checkbox" id="dingtalk-enabled">
                            <span class="slider"></span>
                        </label>
                    </div>
                    <div class="channel-config" id="dingtalk-config">
                        <div class="form-group">
                            <label>Webhook URL:</label>
                            <input type="url" id="dingtalk-webhook" placeholder="https://oapi.dingtalk.com/robot/send?access_token=...">
                        </div>
                        <div class="form-group">
                            <label>自定义关键词 (可选):</label>
                            <input type="text" id="dingtalk-keywords" placeholder="告警,监控">
                        </div>
                        <button class="btn btn-warning" onclick="testDingtalk()">测试钉钉推送</button>
                    </div>
                </div>
                
                <!-- 企业微信配置 -->
                <div class="notification-channel">
                    <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
                        <h4>企业微信群机器人</h4>
                        <label class="switch">
                            <input type="checkbox" id="wechat-enabled">
                            <span class="slider"></span>
                        </label>
                    </div>
                    <div class="channel-config" id="wechat-config">
                        <div class="form-group">
                            <label>Webhook URL:</label>
                            <input type="url" id="wechat-webhook" placeholder="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=...">
                        </div>
                        <div class="form-group">
                            <label>提及用户 (可选):</label>
                            <input type="text" id="wechat-mentioned-list" placeholder="@all 或用户ID，逗号分隔">
                        </div>
                        <button class="btn btn-warning" onclick="testWechat()">测试企业微信推送</button>
                    </div>
                </div>
                
                <!-- 飞书配置 -->
                <div class="notification-channel">
                    <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
                        <h4>飞书群机器人</h4>
                        <label class="switch">
                            <input type="checkbox" id="feishu-enabled">
                            <span class="slider"></span>
                        </label>
                    </div>
                    <div class="channel-config" id="feishu-config">
                        <div class="form-group">
                            <label>Webhook URL:</label>
                            <input type="url" id="feishu-webhook" placeholder="https://open.feishu.cn/open-apis/bot/v2/hook/...">
                        </div>
                        <div class="form-group">
                            <label>签名密钥 (可选):</label>
                            <input type="password" id="feishu-secret" placeholder="签名密钥">
                        </div>
                        <div class="form-group">
                            <label>@用户 (可选):</label>
                            <input type="text" id="feishu-at-users" placeholder="用户ID，逗号分隔">
                        </div>
                        <button class="btn btn-warning" onclick="testFeishu()">测试飞书推送</button>
                    </div>
                </div>
                
                <div style="margin-top: 30px;">
                    <button class="btn" onclick="saveSocialToolsConfig()">保存配置</button>
                    <button class="btn btn-warning" onclick="loadSocialToolsConfig()">重新加载</button>
                </div>
            </div>
            
            <!-- 短信页面 -->
            <div id="sms" class="page">
                <h3>短信配置</h3>
                <div id="sms-alert"></div>
                
                <!-- 阿里云短信配置 -->
                <div class="notification-channel">
                    <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
                        <h4>阿里云短信</h4>
                        <label class="switch">
                            <input type="checkbox" id="sms-enabled">
                            <span class="slider"></span>
                        </label>
                    </div>
                    <div class="channel-config" id="sms-config">
                        <div class="config-grid">
                            <div>
                                <div class="form-group">
                                    <label>Access Key ID:</label>
                                    <input type="text" id="aliyun-access-key" placeholder="您的阿里云Access Key ID">
                                </div>
                                <div class="form-group">
                                    <label>Access Key Secret:</label>
                                    <input type="password" id="aliyun-access-secret" placeholder="您的阿里云Access Key Secret">
                                </div>
                                <div class="form-group">
                                    <label>短信签名:</label>
                                    <input type="text" id="aliyun-sign-name" placeholder="短信签名">
                                </div>
                            </div>
                            <div>
                                <div class="form-group">
                                    <label>短信模板代码:</label>
                                    <input type="text" id="aliyun-template-code" placeholder="SMS_123456789">
                                </div>
                                <div class="form-group">
                                    <label>手机号码 (逗号分隔):</label>
                                    <textarea id="phone-numbers" placeholder="13800138000,13900139000"></textarea>
                                </div>
                            </div>
                        </div>
                        <button class="btn btn-warning" onclick="testSms()">测试短信推送</button>
                    </div>
                </div>
                
                <div style="margin-top: 30px;">
                    <button class="btn" onclick="saveSmsConfig()">保存配置</button>
                    <button class="btn btn-warning" onclick="loadSmsConfig()">重新加载</button>
                </div>
            </div>
            
            <!-- 邮件采集页面 -->
            <div id="email" class="page">
                <h3>邮件采集配置</h3>
                <p>配置邮箱账户，自动采集告警邮件并转发到通知渠道</p>
                
                <!-- 邮件采集开关 -->
                <div class="config-section">
                    <h4>邮件采集服务</h4>
                    <div class="switch-container">
                        <label class="switch">
                            <input type="checkbox" id="emailEnabled">
                            <span class="slider"></span>
                        </label>
                        <span class="switch-label">启用邮件采集</span>
                    </div>
                    
                    <div class="form-group">
                        <label>检查间隔（秒）:</label>
                        <input type="number" id="emailCheckInterval" min="30" max="3600" value="60" placeholder="60">
                        <small>建议设置为60-300秒，避免频繁检查</small>
                    </div>
                </div>
                
                <!-- 邮箱账户配置 -->
                <div class="config-section">
                    <h4>邮箱账户管理</h4>
                    <div id="emailAccountsList"></div>
                    
                    <button class="btn" onclick="addEmailAccount()">添加邮箱账户</button>
                </div>
                
                <!-- 邮件日志 -->
                <div class="config-section">
                    <h4>邮件告警日志</h4>
                    <div style="margin-bottom: 15px;">
                        <button class="btn" onclick="loadEmailLogs()">刷新日志</button>
                        <button class="btn btn-warning" onclick="clearEmailLogs()">清空日志</button>
                    </div>
                    
                    <div class="log-container" id="emailLogContainer">
                        <div class="log-item">暂无邮件告警日志</div>
                    </div>
                </div>
                
                <!-- 邮件服务控制 -->
                <div class="config-section">
                    <h4>服务控制</h4>
                    <div style="display: flex; gap: 10px;">
                        <button class="btn" onclick="startEmailService()">启动邮件服务</button>
                        <button class="btn btn-warning" onclick="stopEmailService()">停止邮件服务</button>
                    </div>
                </div>
                
                <!-- 保存配置 -->
                <div class="config-section">
                    <button class="btn" onclick="saveEmailConfig()">保存邮件配置</button>
                    <button class="btn btn-warning" onclick="loadEmailConfig()">重新加载</button>
                </div>
            </div>
            
            <!-- Webhook配置页面 -->
            <div id="webhook" class="page">
                <h3>Webhook配置</h3>
                <p>配置Webhook接收端点，通过HTTP POST方式接收告警数据并转发到通知渠道</p>
                
                <!-- Webhook服务开关 -->
                <div class="config-section">
                    <h4>Webhook服务</h4>
                    <div class="switch-container">
                        <label class="switch">
                            <input type="checkbox" id="webhookEnabled">
                            <span class="slider"></span>
                        </label>
                        <span class="switch-label">启用Webhook接收</span>
                    </div>
                    
                    <div class="form-group">
                        <label>Webhook端点路径:</label>
                        <input type="text" id="webhookPath" value="/webhook/alert" placeholder="/webhook/alert" readonly>
                        <small>完整URL: http://localhost:5000/webhook/alert</small>
                    </div>
                    
                    <div class="form-group">
                        <label>认证Token（可选）:</label>
                        <input type="text" id="webhookToken" placeholder="输入认证Token以增强安全性">
                        <small>如果设置Token，请求头需包含: Authorization: Bearer &lt;token&gt;</small>
                    </div>
                </div>
                
                <!-- Webhook数据格式说明 -->
                <div class="config-section">
                    <h4>数据格式说明</h4>
                    <div style="background: #f5f5f5; padding: 15px; border-radius: 5px; margin-bottom: 15px;">
                        <p><strong>请求方式:</strong> POST</p>
                        <p><strong>Content-Type:</strong> application/json</p>
                        <p><strong>请求体格式:</strong></p>
                        <pre style="background: #ffffff; padding: 8px 12px; border: 1px solid #d1d5db; border-radius: 6px; overflow-x: auto; color: #374151; font-size: 14px; transition: border-color 0.2s ease;">{
  "title": "告警标题",
  "message": "告警详细信息",
  "level": "warning|error|info",
  "source": "告警来源",
  "timestamp": "2024-01-01T12:00:00Z"
}</pre>
                    </div>
                </div>
                
                <!-- Webhook日志 -->
                <div class="config-section">
                    <h4>Webhook接收日志</h4>
                    <div style="margin-bottom: 15px;">
                        <button class="btn" onclick="loadWebhookLogs()">刷新日志</button>
                        <button class="btn btn-warning" onclick="clearWebhookLogs()">清空日志</button>
                    </div>
                    
                    <div class="log-container" id="webhookLogContainer">
                        <div class="log-item">暂无Webhook接收日志</div>
                    </div>
                </div>
                
                <!-- 测试Webhook -->
                <div class="config-section">
                    <h4>测试Webhook</h4>
                    <div style="margin-bottom: 15px;">
                        <button class="btn" onclick="testWebhook()">发送测试数据</button>
                        <small style="margin-left: 10px;">将发送一条测试告警到Webhook端点</small>
                    </div>
                </div>
                
                <!-- 保存配置 -->
                <div class="config-section">
                    <div id="config-alert"></div>
                    <button class="btn" onclick="saveWebhookConfig()">保存Webhook配置</button>
                    <button class="btn btn-warning" onclick="loadWebhookConfig()">重新加载</button>
                </div>
            </div>
            
            <!-- 告警测试页面 -->
            <div id="test" class="page">
                <h3>告警测试</h3>
                <p>测试告警推送功能是否正常工作</p>
                
                <!-- 告警测试 -->
                <div style="background: white; padding: 20px; border-radius: 10px; margin-bottom: 30px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
                    <h4>选择测试通知渠道</h4>
                    <div style="display: flex; gap: 20px; margin: 15px 0;">
                        <label style="display: flex; align-items: center; cursor: pointer; color: #374151; font-weight: 500;">
                            <input type="checkbox" id="test-dingtalk" checked style="margin-right: 8px;">
                            钉钉群机器人
                        </label>
                        <label style="display: flex; align-items: center; cursor: pointer; color: #374151; font-weight: 500;">
                            <input type="checkbox" id="test-wechat" checked style="margin-right: 8px;">
                            企业微信群机器人
                        </label>
                        <label style="display: flex; align-items: center; cursor: pointer; color: #374151; font-weight: 500;">
                            <input type="checkbox" id="test-sms" checked style="margin-right: 8px;">
                            阿里云短信
                        </label>
                    </div>
                    
                    <div class="form-group" style="margin: 20px 0;">
                        <label>测试消息内容:</label>
                        <textarea id="test-message" placeholder="输入测试消息内容，包含关键词如 error 会触发告警" style="height: 80px;">Test error message from syslog push system</textarea>
                    </div>
                    
                    <div style="margin: 20px 0;">
                        <button class="btn btn-warning" onclick="testAlertWithChannels()">发送测试告警</button>
                    </div>
                    <div id="test-result"></div>
                </div>
            </div>
            
            </div> <!-- content-area -->
        </div> <!-- main-content -->
    </div> <!-- app-container -->
    
    <script>
        let updateInterval;
        let currentPage = 1;
        let totalPages = 1;
        let pageSize = 20;
        
        // 告警事件分页变量
        let currentAlertsPage = 1;
        let totalAlertsPages = 1;
        let alertsPageSize = 20;
        
        // IP统计分页变量
        let currentIpStatsPage = 1;
        let totalIpStatsPages = 1;
        
        function toggleSubmenu(element) {
            event.stopPropagation();
            element.classList.toggle('expanded');
        }
        
        function showPage(pageName) {
            // 隐藏所有页面
            document.querySelectorAll('.page').forEach(page => {
                page.classList.remove('active');
            });
            document.querySelectorAll('.nav-link').forEach(link => {
                link.classList.remove('active');
            });
            
            // 显示选中的页面
            document.getElementById(pageName).classList.add('active');
            event.target.classList.add('active');
            
            // 更新页面标题
            const titles = {
                'dashboard': '导航页',
                'email': '邮件采集',
                'webhook': 'Webhook配置',
                'social-tools': '社交工具',
                'sms': '短信',
                'logs': 'syslog日志',
                'alerts': '告警事件',
                'service-management': '服务管理',
                'basic-config': '基础配置',
                'test': '告警测试'
            };
            document.getElementById('page-title').textContent = titles[pageName] || '未知页面';
        }
        
        function updateStats() {
            fetch('/api/stats')
                .then(response => response.json())
                .then(data => {
                    // 更新仪表盘统计卡片
                    document.getElementById('received-logs').textContent = data.received_logs;
                    document.getElementById('sent-alerts').textContent = data.sent_alerts;
                    document.getElementById('failed-alerts').textContent = data.failed_alerts;
                    document.getElementById('checked-emails').textContent = data.checked_emails || 0;
                    document.getElementById('email-alerts').textContent = data.email_alerts || 0;
                    document.getElementById('uptime').textContent = data.uptime;
                    
                    // 更新顶部栏迷你统计
                    document.getElementById('mini-logs').textContent = data.received_logs;
                    document.getElementById('mini-alerts').textContent = data.sent_alerts;
                    document.getElementById('mini-uptime').textContent = data.uptime;
                    
                    const statusElement = document.getElementById('server-status');
                    const indicatorElement = document.getElementById('status-indicator');
                    const portElement = document.getElementById('server-port');
                    
                    if (data.server_status === 'running') {
                        statusElement.textContent = '运行中';
                        indicatorElement.className = 'status-indicator status-running';
                        portElement.textContent = data.server_port || '-';
                    } else {
                        statusElement.textContent = '已停止';
                        indicatorElement.className = 'status-indicator status-stopped';
                        portElement.textContent = '-';
                    }
                });
        }
        
        function updateTopIpStats() {
            fetch('/api/top_ip_stats')
                .then(response => response.json())
                .then(data => {
                    const container = document.getElementById('top-ip-stats-container');
                    
                    if (!data.top_ip_stats || data.top_ip_stats.length === 0) {
                        container.innerHTML = '<div style="text-align: center; color: #64748b; padding: 20px;">暂无IP统计数据</div>';
                        return;
                    }
                    
                    let html = '';
                    data.top_ip_stats.forEach(stat => {
                        html += `
                            <div style="display: flex; align-items: center; padding: 8px 0; border-bottom: 1px solid #f1f5f9;">
                                <div style="width: 30px; text-align: center; color: #64748b; font-weight: 600;">${stat.rank}</div>
                                <div style="flex: 1; margin-left: 10px;">
                                    <div style="font-family: monospace; color: #374151; font-weight: 600;">${stat.ip}</div>
                                    <div style="font-size: 12px; color: #64748b;">${stat.count} 条日志 (${stat.percentage}%)</div>
                                </div>
                                <div style="flex: 1; min-width: 90px; margin-left: 10px;">
                                    <div style="background: #e2e8f0; height: 12px; border-radius: 6px; overflow: hidden;">
                                        <div style="background: #f59e0b; height: 100%; width: ${stat.percentage}%; transition: width 0.3s ease;"></div>
                                    </div>
                                </div>
                            </div>
                        `;
                    });
                    
                    container.innerHTML = html;
                })
                .catch(error => {
                    console.error('获取TOP10 IP统计失败:', error);
                    document.getElementById('top-ip-stats-container').innerHTML = 
                        '<div style="text-align: center; color: #ef4444; padding: 20px;">加载失败，请稍后重试</div>';
                });
        }
        
        function updateLogs() {
            fetch(`/api/logs?page=${currentPage}&per_page=${pageSize}`)
                .then(response => response.json())
                .then(data => {
                    const container = document.getElementById('logs-container');
                    container.innerHTML = '';
                    
                    if (data.logs.length === 0) {
                        container.innerHTML = '<div class="log-entry"><div class="log-timestamp">暂无日志数据</div></div>';
                    } else {
                        data.logs.forEach(log => {
                            const entry = document.createElement('div');
                            entry.className = 'log-entry';
                            entry.innerHTML = `
                                <div class="log-timestamp">${log.timestamp}</div>
                                <div class="log-source">来源: ${log.source}</div>
                                <div class="log-message">${log.message}</div>
                            `;
                            container.appendChild(entry);
                        });
                    }
                    
                    // 更新分页信息
                    totalPages = data.total_pages;
                    document.getElementById('current-page').textContent = currentPage;
                    document.getElementById('total-pages').textContent = totalPages;
                    
                    // 更新分页按钮状态
                    document.getElementById('first-page').disabled = currentPage === 1;
                    document.getElementById('prev-page').disabled = currentPage === 1;
                    document.getElementById('next-page').disabled = currentPage === totalPages;
                    document.getElementById('last-page').disabled = currentPage === totalPages;
                });
        }
        
        function updateAlerts() {
            fetch(`/api/alerts?page=${currentAlertsPage}&per_page=${alertsPageSize}`)
                .then(response => response.json())
                .then(data => {
                    const container = document.getElementById('alerts-container');
                    container.innerHTML = '';
                    
                    if (data.alerts.length === 0) {
                        container.innerHTML = '<div class="log-entry"><div class="log-timestamp">暂无告警数据</div></div>';
                    } else {
                        data.alerts.forEach(alert => {
                            const entry = document.createElement('div');
                            entry.className = 'log-entry alert-entry';
                            
                            // 构建发送渠道信息
                            let channelsInfo = '';
                            if (alert.channels && alert.channels.length > 0) {
                                const channelNames = {
                                    'dingtalk': '钉钉',
                                    'wechat': '企业微信',
                                    'sms': '短信',
                                    'email': '邮件'
                                };
                                const channelList = alert.channels.map(ch => channelNames[ch] || ch).join(', ');
                                channelsInfo = `<div class="log-channels">发送渠道: ${channelList}</div>`;
                            }
                            
                            entry.innerHTML = `
                                <div class="log-timestamp">${alert.timestamp}</div>
                                <div class="log-source">来源: ${alert.log_entry.source}</div>
                                <div class="log-message">${alert.log_entry.message}</div>
                                ${channelsInfo}
                            `;
                            container.appendChild(entry);
                        });
                    }
                    
                    // 更新分页信息
                    totalAlertsPages = data.total_pages || 1;
                    document.getElementById('current-alerts-page').textContent = currentAlertsPage;
                    document.getElementById('total-alerts-pages').textContent = totalAlertsPages;
                    
                    // 更新分页按钮状态
                    document.getElementById('alerts-first-page').disabled = currentAlertsPage === 1;
                    document.getElementById('alerts-prev-page').disabled = currentAlertsPage === 1;
                    document.getElementById('alerts-next-page').disabled = currentAlertsPage === totalAlertsPages;
                    document.getElementById('alerts-last-page').disabled = currentAlertsPage === totalAlertsPages;
                });
        }
        
        function updateServiceLogs() {
            fetch('/api/service_logs')
                .then(response => response.json())
                .then(data => {
                    const container = document.getElementById('service-logs-container');
                    container.innerHTML = '';
                    
                    if (data.logs.length === 0) {
                        container.innerHTML = '<div class="service-entry"><div class="log-timestamp">暂无服务日志</div></div>';
                        return;
                    }
                    
                    data.logs.slice(-20).forEach(log => {
                        const entry = document.createElement('div');
                        entry.className = 'log-entry service-entry';
                        entry.innerHTML = `
                            <div class="log-timestamp">${log.timestamp}</div>
                            <div class="log-message">${log.message}</div>
                        `;
                        container.appendChild(entry);
                    });
                    
                    container.scrollTop = container.scrollHeight;
                });
        }
        
        function updateIpStats() {
            fetch(`/api/ip_stats?page=${currentIpStatsPage}`)
                .then(response => response.json())
                .then(data => {
                    const tableBody = document.getElementById('ip-stats-table');
                    tableBody.innerHTML = '';
                    
                    if (data.ip_stats.length === 0) {
                        tableBody.innerHTML = '<tr><td colspan="5" style="padding: 20px; text-align: center; color: #64748b;">暂无IP统计数据</td></tr>';
                    } else {
                        data.ip_stats.forEach(stat => {
                            const row = document.createElement('tr');
                            row.style.borderBottom = '1px solid #e2e8f0';
                            
                            // 创建统计图条形，直接使用百分比数值
                             const barWidth = stat.percentage;
                            
                            row.innerHTML = `
                                <td style="padding: 12px; color: #374151;">${stat.rank}</td>
                                <td style="padding: 12px; color: #374151; font-family: monospace;">${stat.ip}</td>
                                <td style="padding: 12px; color: #374151; font-weight: 600;">${stat.count}</td>
                                <td style="padding: 12px; color: #374151;">${stat.percentage}%</td>
                                <td style="padding: 12px;">
                                    <div style="background: #e2e8f0; height: 20px; border-radius: 10px; overflow: hidden;">
                                        <div style="background: #f59e0b; height: 100%; width: ${barWidth}%; transition: width 0.3s ease;"></div>
                                    </div>
                                </td>
                            `;
                            tableBody.appendChild(row);
                        });
                    }
                    
                    // 更新分页信息
                    totalIpStatsPages = data.total_pages;
                    document.getElementById('current-ip-stats-page').textContent = currentIpStatsPage;
                    document.getElementById('total-ip-stats-pages').textContent = totalIpStatsPages;
                    
                    // 更新分页按钮状态
                    document.getElementById('ip-stats-first-page').disabled = currentIpStatsPage === 1;
                    document.getElementById('ip-stats-prev-page').disabled = currentIpStatsPage === 1;
                    document.getElementById('ip-stats-next-page').disabled = currentIpStatsPage === totalIpStatsPages;
                    document.getElementById('ip-stats-last-page').disabled = currentIpStatsPage === totalIpStatsPages;
                });
        }
        
        function loadConfig() {
            fetch('/api/config')
                .then(response => response.json())
                .then(config => {
                    document.getElementById('syslog-port').value = config.syslog_port;
                    document.getElementById('web-port').value = config.web_port;
                    document.getElementById('alert-keywords').value = config.alert_keywords.join(',');
                    document.getElementById('max-logs').value = config.max_logs;
                });
        }
        
        function saveConfig() {
            const config = {
                syslog_port: parseInt(document.getElementById('syslog-port').value),
                web_port: parseInt(document.getElementById('web-port').value),
                alert_keywords: document.getElementById('alert-keywords').value.split(',').map(s => s.trim()).filter(s => s),
                max_logs: parseInt(document.getElementById('max-logs').value)
            };
            
            fetch('/api/config', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(config)
            })
            .then(response => response.json())
            .then(data => {
                showAlert('配置保存成功！', 'success');
            })
            .catch(error => {
                showAlert('配置保存失败: ' + error.message, 'error');
            });
        }
        
        function testAlert() {
            fetch('/api/test_alert', {
                method: 'POST'
            })
            .then(response => response.json())
            .then(data => {
                document.getElementById('test-result').innerHTML = `
                    <div class="alert alert-success">
                        ${data.message}
                    </div>
                `;
            })
            .catch(error => {
                document.getElementById('test-result').innerHTML = `
                    <div class="alert alert-error">
                        测试失败: ${error.message}
                    </div>
                `;
            });
        }
        
        function sendTestMessage() {
            const message = document.getElementById('test-message').value;
            // 这里可以添加发送自定义测试消息的逻辑
            alert('自定义测试消息功能待实现');
        }
        
        function startServer() {
            fetch('/api/server/start', {
                method: 'POST'
            })
            .then(response => response.json())
            .then(data => {
                showAlert(data.message, data.status === 'success' ? 'success' : 'error');
                updateStats();
            });
        }
        
        function stopServer() {
            fetch('/api/server/stop', {
                method: 'POST'
            })
            .then(response => response.json())
            .then(data => {
                showAlert(data.message, 'success');
                updateStats();
            });
        }
        
        function showAlert(message, type) {
            const alertDiv = document.getElementById('config-alert');
            alertDiv.innerHTML = `
                <div class="alert alert-${type}">
                    ${message}
                </div>
            `;
            
            setTimeout(() => {
                alertDiv.innerHTML = '';
            }, 3000);
        }
        
        // 分页功能
        function goToPage(page) {
            if (page < 1 || page > totalPages) return;
            currentPage = page;
            updateLogs();
        }
        
        function changePageSize() {
            pageSize = parseInt(document.getElementById('page-size').value);
            currentPage = 1;
            updateLogs();
        }
        
        // 告警事件分页功能
        function goToAlertsPage(page) {
            if (page < 1 || page > totalAlertsPages) return;
            currentAlertsPage = page;
            updateAlerts();
        }
        
        function changeAlertsPageSize() {
            alertsPageSize = parseInt(document.getElementById('alerts-page-size').value);
            currentAlertsPage = 1;
            updateAlerts();
        }
        
        // IP统计分页功能
        function goToIpStatsPage(page) {
            if (page < 1 || page > totalIpStatsPages) return;
            currentIpStatsPage = page;
            updateIpStats();
        }
        
        function refreshLogs() {
            updateLogs();
        }
        
        function refreshAlerts() {
            updateAlerts();
        }
        
        // 清空功能
        function clearLogs() {
            if (confirm('确定要清空所有日志吗？此操作不可恢复。')) {
                fetch('/api/logs/clear', {
                    method: 'POST'
                })
                .then(response => response.json())
                .then(data => {
                    alert(data.message);
                    currentPage = 1;
                    updateLogs();
                    updateStats();
                })
                .catch(error => {
                    alert('清空失败: ' + error.message);
                });
            }
        }
        
        function clearAlerts() {
             if (confirm('确定要清空所有告警记录吗？此操作不可恢复。')) {
                 fetch('/api/alerts/clear', {
                     method: 'POST'
                 })
                 .then(response => response.json())
                 .then(data => {
                     alert(data.message);
                     updateAlerts();
                     updateStats();
                 })
                 .catch(error => {
                     alert('清空失败: ' + error.message);
                 });
             }
         }
         
         // 通知配置功能
         function loadNotificationConfig() {
             fetch('/api/config')
                 .then(response => response.json())
                 .then(config => {
                     // 钉钉配置
                     document.getElementById('dingtalk-enabled').checked = config.dingtalk_enabled;
                     document.getElementById('dingtalk-webhook').value = config.dingtalk_webhook;
                     document.getElementById('dingtalk-keywords').value = config.dingtalk_keywords;
                     toggleChannelConfig('dingtalk', config.dingtalk_enabled);
                     
                     // 企业微信配置
                     document.getElementById('wechat-enabled').checked = config.wechat_enabled;
                     document.getElementById('wechat-webhook').value = config.wechat_webhook;
                     document.getElementById('wechat-mentioned-list').value = config.wechat_mentioned_list;
                     toggleChannelConfig('wechat', config.wechat_enabled);
                     
                     // 短信配置
                     document.getElementById('sms-enabled').checked = config.sms_enabled;
                     document.getElementById('aliyun-access-key').value = config.aliyun_access_key;
                     document.getElementById('aliyun-access-secret').value = config.aliyun_access_secret;
                     document.getElementById('aliyun-sign-name').value = config.aliyun_sign_name;
                     document.getElementById('aliyun-template-code').value = config.aliyun_template_code;
                     document.getElementById('phone-numbers').value = config.phone_numbers.join(',');
                     toggleChannelConfig('sms', config.sms_enabled);
                 });
         }
         
         function saveNotificationConfig() {
             const config = {
                 // 钉钉配置
                 dingtalk_enabled: document.getElementById('dingtalk-enabled').checked,
                 dingtalk_webhook: document.getElementById('dingtalk-webhook').value,
                 dingtalk_keywords: document.getElementById('dingtalk-keywords').value,
                 
                 // 企业微信配置
                 wechat_enabled: document.getElementById('wechat-enabled').checked,
                 wechat_webhook: document.getElementById('wechat-webhook').value,
                 wechat_mentioned_list: document.getElementById('wechat-mentioned-list').value,
                 
                 // 短信配置
                 sms_enabled: document.getElementById('sms-enabled').checked,
                 aliyun_access_key: document.getElementById('aliyun-access-key').value,
                 aliyun_access_secret: document.getElementById('aliyun-access-secret').value,
                 aliyun_sign_name: document.getElementById('aliyun-sign-name').value,
                 aliyun_template_code: document.getElementById('aliyun-template-code').value,
                 phone_numbers: document.getElementById('phone-numbers').value.split(',').map(s => s.trim()).filter(s => s)
             };
             
             fetch('/api/config', {
                 method: 'POST',
                 headers: {
                     'Content-Type': 'application/json'
                 },
                 body: JSON.stringify(config)
             })
             .then(response => response.json())
             .then(data => {
                 showNotificationAlert('通知配置保存成功！', 'success');
             })
             .catch(error => {
                 showNotificationAlert('通知配置保存失败: ' + error.message, 'error');
             });
         }
         
         function toggleChannelConfig(channel, enabled) {
             const configDiv = document.getElementById(channel + '-config');
             if (enabled) {
                 configDiv.classList.remove('disabled');
             } else {
                 configDiv.classList.add('disabled');
             }
         }
         
         function testDingtalk() {
             fetch('/api/notification/test/dingtalk', {
                 method: 'POST'
             })
             .then(response => response.json())
             .then(data => {
                 showNotificationAlert(data.message, data.status === 'success' ? 'success' : 'error');
             })
             .catch(error => {
                 showNotificationAlert('测试失败: ' + error.message, 'error');
             });
         }
         
         function testWechat() {
             fetch('/api/notification/test/wechat', {
                 method: 'POST'
             })
             .then(response => response.json())
             .then(data => {
                 showNotificationAlert(data.message, data.status === 'success' ? 'success' : 'error');
             })
             .catch(error => {
                 showNotificationAlert('测试失败: ' + error.message, 'error');
             });
         }
         
         function testFeishu() {
             fetch('/api/notification/test/feishu', {
                 method: 'POST'
             })
             .then(response => response.json())
             .then(data => {
                 showSocialToolsAlert(data.message, data.status === 'success' ? 'success' : 'error');
             })
             .catch(error => {
                 showSocialToolsAlert('测试失败: ' + error.message, 'error');
             });
         }
         
         function testSms() {
             fetch('/api/notification/test/sms', {
                 method: 'POST'
             })
             .then(response => response.json())
             .then(data => {
                 showNotificationAlert(data.message, data.status === 'success' ? 'success' : 'error');
             })
             .catch(error => {
                 showNotificationAlert('测试失败: ' + error.message, 'error');
             });
         }
         
         function showNotificationAlert(message, type) {
             const alertDiv = document.getElementById('notification-alert');
             alertDiv.innerHTML = `
                 <div class="alert alert-${type}">
                     ${message}
                 </div>
             `;
         }
         
         // 社交工具配置函数
         function saveSocialToolsConfig() {
             const config = {
                 dingtalk_enabled: document.getElementById('dingtalk-enabled').checked,
                 dingtalk_webhook: document.getElementById('dingtalk-webhook').value,
                 dingtalk_keywords: document.getElementById('dingtalk-keywords').value,
                 wechat_enabled: document.getElementById('wechat-enabled').checked,
                 wechat_webhook: document.getElementById('wechat-webhook').value,
                 wechat_mentioned_list: document.getElementById('wechat-mentioned-list').value,
                 feishu_enabled: document.getElementById('feishu-enabled').checked,
                 feishu_webhook: document.getElementById('feishu-webhook').value,
                 feishu_secret: document.getElementById('feishu-secret').value,
                 feishu_at_users: document.getElementById('feishu-at-users').value
             };
             
             fetch('/api/config', {
                 method: 'POST',
                 headers: {
                     'Content-Type': 'application/json'
                 },
                 body: JSON.stringify(config)
             })
             .then(response => response.json())
             .then(data => {
                 showSocialToolsAlert('即时通讯配置保存成功！', 'success');
             })
             .catch(error => {
                 showSocialToolsAlert('即时通讯配置保存失败: ' + error.message, 'error');
             });
         }
         
         function loadSocialToolsConfig() {
             fetch('/api/config')
                 .then(response => response.json())
                 .then(config => {
                     document.getElementById('dingtalk-enabled').checked = config.dingtalk_enabled;
                     document.getElementById('dingtalk-webhook').value = config.dingtalk_webhook;
                     document.getElementById('dingtalk-keywords').value = config.dingtalk_keywords;
                     document.getElementById('wechat-enabled').checked = config.wechat_enabled;
                     document.getElementById('wechat-webhook').value = config.wechat_webhook;
                     document.getElementById('wechat-mentioned-list').value = config.wechat_mentioned_list;
                     document.getElementById('feishu-enabled').checked = config.feishu_enabled;
                     document.getElementById('feishu-webhook').value = config.feishu_webhook;
                     document.getElementById('feishu-secret').value = config.feishu_secret;
                     document.getElementById('feishu-at-users').value = config.feishu_at_users;
                     toggleChannelConfig('dingtalk', config.dingtalk_enabled);
                     toggleChannelConfig('wechat', config.wechat_enabled);
                     toggleChannelConfig('feishu', config.feishu_enabled);
                 });
         }
         
         function showSocialToolsAlert(message, type) {
             const alertDiv = document.getElementById('social-tools-alert');
             alertDiv.innerHTML = `
                 <div class="alert alert-${type}">
                     ${message}
                 </div>
             `;
             setTimeout(() => {
                 alertDiv.innerHTML = '';
             }, 3000);
         }
         
         // 短信配置函数
         function saveSmsConfig() {
             const config = {
                 sms_enabled: document.getElementById('sms-enabled').checked,
                 aliyun_access_key: document.getElementById('aliyun-access-key').value,
                 aliyun_access_secret: document.getElementById('aliyun-access-secret').value,
                 aliyun_sign_name: document.getElementById('aliyun-sign-name').value,
                 aliyun_template_code: document.getElementById('aliyun-template-code').value,
                 phone_numbers: document.getElementById('phone-numbers').value.split(',').map(s => s.trim()).filter(s => s)
             };
             
             fetch('/api/config', {
                 method: 'POST',
                 headers: {
                     'Content-Type': 'application/json'
                 },
                 body: JSON.stringify(config)
             })
             .then(response => response.json())
             .then(data => {
                 showSmsAlert('短信配置保存成功！', 'success');
             })
             .catch(error => {
                 showSmsAlert('短信配置保存失败: ' + error.message, 'error');
             });
         }
         
         function loadSmsConfig() {
             fetch('/api/config')
                 .then(response => response.json())
                 .then(config => {
                     document.getElementById('sms-enabled').checked = config.sms_enabled;
                     document.getElementById('aliyun-access-key').value = config.aliyun_access_key;
                     document.getElementById('aliyun-access-secret').value = config.aliyun_access_secret;
                     document.getElementById('aliyun-sign-name').value = config.aliyun_sign_name;
                     document.getElementById('aliyun-template-code').value = config.aliyun_template_code;
                     document.getElementById('phone-numbers').value = config.phone_numbers.join(',');
                     toggleChannelConfig('sms', config.sms_enabled);
                 });
         }
         
         function showSmsAlert(message, type) {
             const alertDiv = document.getElementById('sms-alert');
             alertDiv.innerHTML = `
                 <div class="alert alert-${type}">
                     ${message}
                 </div>
             `;
             setTimeout(() => {
                 alertDiv.innerHTML = '';
             }, 3000);
         }
         
         // 基础配置函数
         function saveBasicConfig() {
             const config = {
                 syslog_port: parseInt(document.getElementById('syslog-port').value),
                 web_port: parseInt(document.getElementById('web-port').value),
                 alert_keywords: document.getElementById('alert-keywords').value.split(',').map(s => s.trim()).filter(s => s),
                 max_logs: parseInt(document.getElementById('max-logs').value)
             };
             
             fetch('/api/config', {
                 method: 'POST',
                 headers: {
                     'Content-Type': 'application/json'
                 },
                 body: JSON.stringify(config)
             })
             .then(response => response.json())
             .then(data => {
                 showBasicConfigAlert('基础配置保存成功！', 'success');
             })
             .catch(error => {
                 showBasicConfigAlert('基础配置保存失败: ' + error.message, 'error');
             });
         }
         
         function loadBasicConfig() {
             fetch('/api/config')
                 .then(response => response.json())
                 .then(config => {
                     document.getElementById('syslog-port').value = config.syslog_port;
                     document.getElementById('web-port').value = config.web_port;
                     document.getElementById('alert-keywords').value = config.alert_keywords.join(',');
                     document.getElementById('max-logs').value = config.max_logs;
                 });
         }
         
         function showBasicConfigAlert(message, type) {
             const alertDiv = document.getElementById('basic-config-alert');
             alertDiv.innerHTML = `
                 <div class="alert alert-${type}">
                     ${message}
                 </div>
             `;
             setTimeout(() => {
                 alertDiv.innerHTML = '';
             }, 3000);
         }
         
         function showNotificationAlert(message, type) {
             const alertDiv = document.getElementById('notification-alert');
             alertDiv.innerHTML = `
                 <div class="alert alert-${type}">
                     ${message}
                 </div>
             `;
             
             setTimeout(() => {
                 alertDiv.innerHTML = '';
             }, 3000);
         }
         
         // 告警测试功能
         function testAlertWithChannels() {
             const selectedChannels = [];
             
             if (document.getElementById('test-dingtalk').checked) {
                 selectedChannels.push('dingtalk');
             }
             if (document.getElementById('test-wechat').checked) {
                 selectedChannels.push('wechat');
             }
             if (document.getElementById('test-sms').checked) {
                 selectedChannels.push('sms');
             }
             
             if (selectedChannels.length === 0) {
                 showTestAlert('请至少选择一个通知渠道', 'error');
                 return;
             }
             
             // 获取自定义消息内容
             const customMessage = document.getElementById('test-message').value.trim();
             
             showTestAlert('正在发送测试告警...', 'info');
             
             // 首先发送自定义测试消息到日志系统
             if (customMessage) {
                 fetch('/api/test_message', {
                     method: 'POST',
                     headers: {
                         'Content-Type': 'application/json'
                     },
                     body: JSON.stringify({ message: customMessage })
                 })
                 .then(response => response.json())
                 .then(data => {
                     // 如果消息触发了告警，则不需要额外测试渠道
                     if (data.message.includes('触发告警推送')) {
                         showTestAlert(`✅ ${data.message}`, 'success');
                         return;
                     }
                     
                     // 如果没有触发告警，则手动测试选中的渠道
                     testSelectedChannels(selectedChannels, customMessage);
                 })
                 .catch(error => {
                     showTestAlert('发送测试消息失败: ' + error.message, 'error');
                 });
             } else {
                 // 如果没有自定义消息，直接测试渠道
                 testSelectedChannels(selectedChannels, '这是一条测试告警消息');
             }
         }
         
         function testSelectedChannels(selectedChannels, testMessage) {
             // 并行测试所有选中的渠道
             const testPromises = selectedChannels.map(channel => {
                 return fetch(`/api/notification/test/${channel}`, {
                     method: 'POST'
                 })
                 .then(response => response.json())
                 .then(data => ({ channel, ...data }))
                 .catch(error => ({ channel, status: 'error', message: error.message }));
             });
             
             Promise.all(testPromises)
                 .then(results => {
                     let successCount = 0;
                     let failCount = 0;
                     let messages = [];
                     
                     results.forEach(result => {
                         const channelNames = {
                             'dingtalk': '钉钉',
                             'wechat': '企业微信',
                             'sms': '短信'
                         };
                         
                         if (result.status === 'success') {
                             successCount++;
                             messages.push(`✅ ${channelNames[result.channel]}: ${result.message}`);
                         } else {
                             failCount++;
                             messages.push(`❌ ${channelNames[result.channel]}: ${result.message}`);
                         }
                     });
                     
                     const summary = `测试完成！成功: ${successCount}, 失败: ${failCount}`;
                     const allMessages = [summary, ...messages].join('<br>');
                     
                     showTestAlert(allMessages, failCount === 0 ? 'success' : 'warning');
                 });
         }
         
         function testAlert() {
             // 兼容原有的testAlert函数
             testAlertWithChannels();
         }
         
         function sendTestMessage() {
             const message = document.getElementById('test-message').value;
             if (!message.trim()) {
                 showTestAlert('请输入测试消息内容', 'error');
                 return;
             }
             
             fetch('/api/test_message', {
                 method: 'POST',
                 headers: {
                     'Content-Type': 'application/json'
                 },
                 body: JSON.stringify({ message: message })
             })
             .then(response => response.json())
             .then(data => {
                 showTestAlert(data.message, 'success');
             })
             .catch(error => {
                 showTestAlert('发送失败: ' + error.message, 'error');
             });
         }
         
         function showTestAlert(message, type) {
             const alertDiv = document.getElementById('test-result');
             alertDiv.innerHTML = `
                 <div class="alert alert-${type}">
                     ${message}
                 </div>
             `;
             
             setTimeout(() => {
                 alertDiv.innerHTML = '';
             }, 5000);
         }
        
        // 邮件采集功能
        let emailAccounts = [];
        
        function loadEmailConfig() {
            fetch('/api/email/config')
                .then(response => response.json())
                .then(data => {
                    document.getElementById('emailEnabled').checked = data.email_enabled;
                    document.getElementById('emailCheckInterval').value = data.email_check_interval;
                    emailAccounts = data.email_accounts || [];
                    renderEmailAccounts();
                })
                .catch(error => {
                    console.error('加载邮件配置失败:', error);
                });
        }
        
        function saveEmailConfig() {
            const config = {
                email_enabled: document.getElementById('emailEnabled').checked,
                email_check_interval: parseInt(document.getElementById('emailCheckInterval').value),
                email_accounts: emailAccounts
            };
            
            fetch('/api/email/config', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(config)
            })
            .then(response => response.json())
            .then(data => {
                showEmailAlert(data.message, data.status === 'success' ? 'success' : 'error');
            })
            .catch(error => {
                showEmailAlert('保存配置失败: ' + error.message, 'error');
            });
        }
        
        function addEmailAccount() {
            const newAccount = {
                name: '新邮箱',
                enabled: true,
                server: '',
                port: 993,
                use_ssl: true,
                username: '',
                password: '',
                keywords: ['告警', 'alert', 'error'],
                sender_filter: '',
                subject_filter: ''
            };
            
            emailAccounts.push(newAccount);
            renderEmailAccounts();
        }
        
        function removeEmailAccount(index) {
            if (confirm('确定要删除这个邮箱账户吗？')) {
                emailAccounts.splice(index, 1);
                renderEmailAccounts();
            }
        }
        
        function renderEmailAccounts() {
            const container = document.getElementById('emailAccountsList');
            
            if (emailAccounts.length === 0) {
                container.innerHTML = '<p>暂无邮箱账户，请点击"添加邮箱账户"按钮添加。</p>';
                return;
            }
            
            let html = '';
            emailAccounts.forEach((account, index) => {
                html += `
                    <div class="email-account-card" style="border: 1px solid #ddd; padding: 15px; margin-bottom: 15px; border-radius: 5px;">
                        <div style="display: flex; justify-content: between; align-items: center; margin-bottom: 10px;">
                            <h5 style="margin: 0;">${account.name}</h5>
                            <div>
                                <button class="btn btn-sm" onclick="testEmailAccount(${index})">测试连接</button>
                                <button class="btn btn-sm btn-warning" onclick="removeEmailAccount(${index})">删除</button>
                            </div>
                        </div>
                        
                        <div class="form-row">
                            <div class="form-group" style="flex: 1; margin-right: 10px;">
                                <label>账户名称:</label>
                                <input type="text" value="${account.name}" onchange="updateEmailAccount(${index}, 'name', this.value)">
                            </div>
                            <div class="form-group" style="width: 100px;">
                                <label>启用:</label>
                                <input type="checkbox" ${account.enabled ? 'checked' : ''} onchange="updateEmailAccount(${index}, 'enabled', this.checked)">
                            </div>
                        </div>
                        
                        <div class="form-row">
                            <div class="form-group" style="flex: 2; margin-right: 10px;">
                                <label>IMAP服务器:</label>
                                <input type="text" value="${account.server}" placeholder="imap.example.com" onchange="updateEmailAccount(${index}, 'server', this.value)">
                            </div>
                            <div class="form-group" style="width: 80px; margin-right: 10px;">
                                <label>端口:</label>
                                <input type="number" value="${account.port}" onchange="updateEmailAccount(${index}, 'port', parseInt(this.value))">
                            </div>
                            <div class="form-group" style="width: 80px;">
                                <label>SSL:</label>
                                <input type="checkbox" ${account.use_ssl ? 'checked' : ''} onchange="updateEmailAccount(${index}, 'use_ssl', this.checked)">
                            </div>
                        </div>
                        
                        <div class="form-row">
                            <div class="form-group" style="flex: 1; margin-right: 10px;">
                                <label>用户名:</label>
                                <input type="text" value="${account.username}" placeholder="user@example.com" onchange="updateEmailAccount(${index}, 'username', this.value)">
                            </div>
                            <div class="form-group" style="flex: 1;">
                                <label>密码:</label>
                                <input type="password" value="${account.password}" placeholder="邮箱密码或授权码" onchange="updateEmailAccount(${index}, 'password', this.value)">
                            </div>
                        </div>
                        
                        <div class="form-group">
                            <label>告警关键词（用逗号分隔）:</label>
                            <input type="text" value="${account.keywords.join(', ')}" placeholder="告警, alert, error" onchange="updateEmailAccount(${index}, 'keywords', this.value.split(',').map(k => k.trim()).filter(k => k))">
                        </div>
                        
                        <div class="form-row">
                            <div class="form-group" style="flex: 1; margin-right: 10px;">
                                <label>发件人过滤（可选）:</label>
                                <input type="text" value="${account.sender_filter}" placeholder="只处理包含此文本的发件人" onchange="updateEmailAccount(${index}, 'sender_filter', this.value)">
                            </div>
                            <div class="form-group" style="flex: 1;">
                                <label>主题过滤（可选）:</label>
                                <input type="text" value="${account.subject_filter}" placeholder="只处理包含此文本的主题" onchange="updateEmailAccount(${index}, 'subject_filter', this.value)">
                            </div>
                        </div>
                    </div>
                `;
            });
            
            container.innerHTML = html;
        }
        
        function updateEmailAccount(index, field, value) {
            if (emailAccounts[index]) {
                emailAccounts[index][field] = value;
            }
        }
        
        function testEmailAccount(index) {
            const account = emailAccounts[index];
            if (!account.server || !account.username || !account.password) {
                showEmailAlert('请先完善邮箱配置信息', 'error');
                return;
            }
            
            showEmailAlert('正在测试邮箱连接...', 'info');
            
            fetch('/api/email/test', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    server: account.server,
                    port: account.port,
                    use_ssl: account.use_ssl,
                    username: account.username,
                    password: account.password
                })
            })
            .then(response => response.json())
            .then(data => {
                showEmailAlert(data.message, data.status === 'success' ? 'success' : 'error');
            })
            .catch(error => {
                showEmailAlert('测试连接失败: ' + error.message, 'error');
            });
        }
        
        function startEmailService() {
            fetch('/api/email/service/start', {
                method: 'POST'
            })
            .then(response => response.json())
            .then(data => {
                showEmailAlert(data.message, data.status === 'success' ? 'success' : 'error');
            })
            .catch(error => {
                showEmailAlert('启动服务失败: ' + error.message, 'error');
            });
        }
        
        function stopEmailService() {
            fetch('/api/email/service/stop', {
                method: 'POST'
            })
            .then(response => response.json())
            .then(data => {
                showEmailAlert(data.message, data.status === 'success' ? 'success' : 'error');
            })
            .catch(error => {
                showEmailAlert('停止服务失败: ' + error.message, 'error');
            });
        }
        
        function loadEmailLogs() {
            fetch('/api/emails?page=1&per_page=50')
                .then(response => response.json())
                .then(data => {
                    const container = document.getElementById('emailLogContainer');
                    
                    if (data.emails.length === 0) {
                        container.innerHTML = '<div class="log-item">暂无邮件告警日志</div>';
                        return;
                    }
                    
                    let html = '';
                    data.emails.forEach(email => {
                        html += `
                            <div class="log-item">
                                <div class="log-time">${email.timestamp}</div>
                                <div class="log-content">
                                    <strong>账户:</strong> ${email.account}<br>
                                    <strong>发件人:</strong> ${email.sender}<br>
                                    <strong>主题:</strong> ${email.subject}<br>
                                    <strong>匹配关键词:</strong> ${email.matched_keywords.join(', ')}<br>
                                    <strong>内容:</strong> ${email.body}
                                </div>
                            </div>
                        `;
                    });
                    
                    container.innerHTML = html;
                })
                .catch(error => {
                    console.error('加载邮件日志失败:', error);
                });
        }
        
        function clearEmailLogs() {
            if (confirm('确定要清空所有邮件日志吗？')) {
                fetch('/api/emails/clear', {
                    method: 'POST'
                })
                .then(response => response.json())
                .then(data => {
                    showEmailAlert(data.message, 'success');
                    loadEmailLogs();
                })
                .catch(error => {
                    showEmailAlert('清空日志失败: ' + error.message, 'error');
                });
            }
        }
        
        function showEmailAlert(message, type) {
            // 创建临时提示元素
            const alertDiv = document.createElement('div');
            alertDiv.className = `alert alert-${type}`;
            alertDiv.textContent = message;
            alertDiv.style.position = 'fixed';
            alertDiv.style.top = '20px';
            alertDiv.style.right = '20px';
            alertDiv.style.zIndex = '9999';
            alertDiv.style.padding = '10px 15px';
            alertDiv.style.borderRadius = '5px';
            alertDiv.style.backgroundColor = type === 'success' ? '#d4edda' : type === 'error' ? '#f8d7da' : '#d1ecf1';
            alertDiv.style.border = `1px solid ${type === 'success' ? '#c3e6cb' : type === 'error' ? '#f5c6cb' : '#bee5eb'}`;
            alertDiv.style.color = type === 'success' ? '#155724' : type === 'error' ? '#721c24' : '#0c5460';
            
            document.body.appendChild(alertDiv);
            
            setTimeout(() => {
                document.body.removeChild(alertDiv);
            }, 5000);
        }
        
        // 初始化
        document.addEventListener('DOMContentLoaded', function() {
            loadConfig();
            loadNotificationConfig();
            loadSocialToolsConfig();
            loadEmailConfig();
            updateStats();
            updateLogs();
            updateAlerts();
            updateServiceLogs();
            updateIpStats();
            updateTopIpStats();
            
            // 添加开关按钮事件监听器
            document.getElementById('dingtalk-enabled').addEventListener('change', function() {
                toggleChannelConfig('dingtalk', this.checked);
            });
            
            document.getElementById('wechat-enabled').addEventListener('change', function() {
                toggleChannelConfig('wechat', this.checked);
            });
            
            document.getElementById('feishu-enabled').addEventListener('change', function() {
                toggleChannelConfig('feishu', this.checked);
            });
            
            document.getElementById('sms-enabled').addEventListener('change', function() {
                toggleChannelConfig('sms', this.checked);
            });
            
            // 设置定时更新（不包括日志，因为分页模式下不自动刷新）
            updateInterval = setInterval(() => {
                updateStats();
                updateServiceLogs();
                updateIpStats();
                updateTopIpStats();
            }, 2000);
            
            // 加载webhook配置
            loadWebhookConfig();
        });
        
        // Webhook相关函数
        function saveWebhookConfig() {
            const config = {
                webhook_enabled: document.getElementById('webhookEnabled').checked,
                webhook_path: document.getElementById('webhookPath').value,
                webhook_token: document.getElementById('webhookToken').value
            };
            
            fetch('/api/webhook/config', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(config)
            })
            .then(response => response.json())
            .then(data => {
                showAlert(data.message, data.status === 'success' ? 'success' : 'error');
            })
            .catch(error => {
                showAlert('保存Webhook配置失败: ' + error.message, 'error');
            });
        }
        
        function loadWebhookConfig() {
            fetch('/api/webhook/config')
            .then(response => response.json())
            .then(data => {
                if (data.status === 'success') {
                    document.getElementById('webhookEnabled').checked = data.config.webhook_enabled || false;
                    document.getElementById('webhookPath').value = data.config.webhook_path || '/webhook/alert';
                    document.getElementById('webhookToken').value = data.config.webhook_token || '';
                }
            })
            .catch(error => {
                console.error('加载Webhook配置失败:', error);
            });
        }
        
        function loadWebhookLogs() {
            fetch('/api/webhook/logs')
            .then(response => response.json())
            .then(data => {
                const container = document.getElementById('webhookLogContainer');
                if (data.logs && data.logs.length > 0) {
                    container.innerHTML = data.logs.map(log => 
                        `<div class="log-item">
                            <span class="log-time">${log.timestamp}</span>
                            <span class="log-level log-level-${log.level}">${log.level.toUpperCase()}</span>
                            <span class="log-message">${log.message}</span>
                        </div>`
                    ).join('');
                } else {
                    container.innerHTML = '<div class="log-item">暂无Webhook接收日志</div>';
                }
            })
            .catch(error => {
                console.error('加载Webhook日志失败:', error);
            });
        }
        
        function clearWebhookLogs() {
            if (confirm('确定要清空所有Webhook日志吗？')) {
                fetch('/api/webhook/logs', {
                    method: 'DELETE'
                })
                .then(response => response.json())
                .then(data => {
                    showAlert(data.message, data.status === 'success' ? 'success' : 'error');
                    if (data.status === 'success') {
                        loadWebhookLogs();
                    }
                })
                .catch(error => {
                    showAlert('清空Webhook日志失败: ' + error.message, 'error');
                });
            }
        }
        
        function testWebhook() {
            const testData = {
                title: '测试告警',
                message: '这是一条来自Webhook的测试告警消息',
                level: 'info',
                source: 'webhook-test',
                timestamp: new Date().toISOString()
            };
            
            fetch('/webhook/alert', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(testData)
            })
            .then(response => response.json())
            .then(data => {
                showAlert(data.message, data.status === 'success' ? 'success' : 'error');
                if (data.status === 'success') {
                    loadWebhookLogs();
                }
            })
            .catch(error => {
                showAlert('测试Webhook失败: ' + error.message, 'error');
            });
        }
    </script>
</body>
</html>